package eval

import (
	"showen/lex"
	"showen/obj"
	"showen/parse"
	"testing"
)

func TestEvalDefine001(t *testing.T) {
	tests := []struct {
		input string
		want  []string
	}{
		{
			"(define x 1) x",
			[]string{"", "1"},
		},
		{
			"(define (f x ) (* x x)) (f 10)",
			[]string{"", "100"},
		},
	}

	env := obj.NewEnvironment()
	RegisterBuiltinProcedures(env)

	for _, tt := range tests {
		lexer := lex.NewLexer(tt.input)
		tokens := lexer.ReadTokens()
		parser := parse.NewParser(tokens)
		exprs, err := parser.ParseProgram()
		if err != nil {
			t.Fatalf("parser.ParseExpression() error = %v", err)
		}

		for i, expr := range exprs {
			var o obj.Object
			o, err = EvalExpression(expr, env)
			if err != nil {
				t.Fatalf("EvalExpression() error = %v", err)
			}

			if o.Inspect() != tt.want[i] {
				t.Errorf("EvalExpression() = %v, want %v", o.Inspect(), tt.want[0])
			}
		}
	}
}
